package com.qf.task;

import com.qf.service.ProductReviewLikeDislikeService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @Author Ayases
 * @Date 2025/6/11 18:01
 * @Desc
 */

@Component
public class ProductTask {

    @Resource
    ProductReviewLikeDislikeService productReviewLikeDislikeService;

    @Resource
    RedissonClient redissonClient;

    // 日志记录器
    private static final Logger log = LoggerFactory.getLogger(ProductTask.class);


    // 每10秒执行一次，更新点赞数
    // @Scheduled(cron = "0/10 * * * * ?")
    // 每天零点执行一次，更新点赞数
    // @Scheduled(cron = "0 0 0 * * ?")

    // 每分钟执行一次（每分钟的0秒时刻执行），更新点赞数
    @Scheduled(cron = "0 * * * * ?")
    public void updateCommentLikeOrDislikeTask() {

        // 1. 获取分布式锁对象
        // 使用统一的锁名称确保分布式环境下的唯一性
        RLock lock = redissonClient.getLock("lock:updateCommentLikeOrDislikeTask");

        try {
            // 2. 尝试获取分布式锁
            // 参数说明：
            //   waitTime - 等待锁的最长时间（0表示不等待，立即返回）
            //   leaseTime - 锁的持有时间（60秒）
            //   unit - 时间单位
            if (lock.tryLock(0, 60, TimeUnit.SECONDS)) {
                // 3. 成功获取锁后执行核心业务逻辑
                log.info("【定时任务】开始执行评论点赞点踩数据更新...");

                // 记录任务开始时间
                long startTime = System.currentTimeMillis();

                // 执行实际的业务逻辑
                productReviewLikeDislikeService.updateCommentLikeOrDislikeTask();

                // 计算并记录执行耗时
                long duration = System.currentTimeMillis() - startTime;
                log.info("【定时任务】评论点赞点踩数据更新完成，耗时: {} 毫秒", duration);
            } else {
                // 4. 未能获取锁（说明其他节点正在执行此任务）
                log.info("【定时任务】获取锁失败，跳过本次执行");
            }
        } catch (InterruptedException e) {
            // 5. 处理线程中断异常
            Thread.currentThread().interrupt();
            log.error("【定时任务】执行过程中被中断", e);
        } finally {
            // 6. 确保锁被正确释放
            if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
                try {
                    lock.unlock();
                    log.debug("【定时任务】分布式锁已释放");
                } catch (IllegalMonitorStateException e) {
                    log.warn("【定时任务】释放锁时发生异常（可能锁已超时自动释放）", e);
                }
            }
        }
    }

}
